package com.swt.gap.service.impl;

import com.alibaba.fastjson.JSON;
import com.swt.gap.common.constant.GraphDbConstant;
import com.swt.gap.dao.NodeFilterDao;
import com.swt.gap.model.entity.NodeFilter;
import com.swt.gap.model.params.PropertyFilterConfig;
import com.swt.gap.model.vo.EventNodeRelMediaVO;
import com.swt.gap.model.vo.FilterVO;
import com.swt.gap.model.vo.NodeFilterVO;
import com.swt.gap.service.NodeFilterService;
import com.swt.gap.util.StringFilter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 请填写说明
 *
 * @author sx
 * @date 2020/6/23 10:39
 */
@Service
public class NodeFilterServiceImpl implements NodeFilterService {

    private final NodeFilterDao nodeFilterDao;

    public NodeFilterServiceImpl(NodeFilterDao nodeFilterDao) {
        this.nodeFilterDao = nodeFilterDao;
    }

    @Override
    public Integer addNodeFilter(NodeFilterVO nodeFilterVO) {
        nodeFilterVO.setContent(JSON.toJSONString(nodeFilterVO.getPropertyFilterConfigs()));
        return nodeFilterDao.insertSelective(nodeFilterVO);
    }

    @Override
    public Integer updateNodeFilter(NodeFilterVO nodeFilterVO) {
        nodeFilterVO.setContent(JSON.toJSONString(nodeFilterVO.getPropertyFilterConfigs()));
        return nodeFilterDao.updateByPrimaryKeySelective(nodeFilterVO);
    }

    @Override
    public Integer deleteNodeFilter(Integer filterId) {
        return nodeFilterDao.deleteByPrimaryKey(filterId);
    }

    @Override
    public NodeFilterVO getFilterById(Integer filterId) {
        NodeFilter nodeFilter = nodeFilterDao.selectByPrimaryKey(filterId);
        NodeFilterVO nodeFilterVO = new NodeFilterVO();
        BeanUtils.copyProperties(nodeFilter, nodeFilterVO);
        nodeFilterVO.setContent("");
        nodeFilterVO.setPropertyFilterConfigs(JSON.parseArray(nodeFilter.getContent(), PropertyFilterConfig.class));
        return nodeFilterVO;
    }

    @Override
    public List<NodeFilterVO> listAllFilterByUserIdAndTaskId(Integer userId, Integer taskId) {
        List<NodeFilterVO> retValue = new ArrayList<>();
        List<NodeFilter> nodeFilters = nodeFilterDao.listAllFilterByUserIdAndTaskId(userId, taskId);
        nodeFilters.forEach(nodeFilter -> {
            NodeFilterVO nodeFilterVO = new NodeFilterVO();
            BeanUtils.copyProperties(nodeFilter, nodeFilterVO);
            nodeFilterVO.setPropertyFilterConfigs(JSON.parseArray(nodeFilter.getContent(), PropertyFilterConfig.class));
            nodeFilterVO.setContent("");
            retValue.add(nodeFilterVO);
        });
        return retValue;
    }

    @Override
    public List<EventNodeRelMediaVO> filter(FilterVO record) {
        List<EventNodeRelMediaVO> retValue = new ArrayList<>();
        record.getNodes().forEach(node -> {
            boolean isMatch = false;
            for(PropertyFilterConfig propertyFilterConfig : record.getPropertyFilterConfigs()) {
                String realValue = "";
                if (GraphDbConstant.EVENT_TYPE.equals(propertyFilterConfig.getPropertyKey())) {
                    List<String> labels = node.getLabels();
                    realValue = labels.get(1);
                } else {
                    realValue = node.getProperties().get(propertyFilterConfig.getPropertyKey()).toString();
                    if (null == realValue && GraphDbConstant.PROPERTY_KEY_NAME.equals(propertyFilterConfig.getPropertyKey())){
                        realValue = (String) node.getProperties().get(GraphDbConstant.PROPERTY_NAME);
                    }
                }
                if (!StringUtils.isEmpty(realValue)) {
                    isMatch = StringFilter.isMatchCondition(realValue, propertyFilterConfig.getValue(), propertyFilterConfig.getConditionType());
                    if (!isMatch) {
                        break;
                    }
                }
            }
            if (isMatch) {
                retValue.add(node);
            }
        });
        return retValue;
    }
}
